//
//  SSCIAPUnityAdapter.m
//  Unity-iPhone
//
//  Created by xuzepei on 16/5/23.
//
//

#import "SSCIAPUnityAdapter.h"

//char* cStringCopy(const char* string)
//{
//    if (string == NULL)
//        return NULL;
//    
//    char* res = (char*)malloc(strlen(string) + 1);
//    strcpy(res, string);
//    
//    return res;
//}

@implementation SSCIAPUnityAdapter

+ (SSCIAPUnityAdapter*)getInstance
{
    static SSCIAPUnityAdapter* sharedInstance = nil;
    static dispatch_once_t token;
    
    dispatch_once(&token, ^{
        sharedInstance = [[SSCIAPUnityAdapter alloc] init];
        [[IAPurchase sharedPurchase] setDelegate:sharedInstance];
    });
    
    return sharedInstance;
}

- (void)setGameObjectName:(char*)name
{
    if(name && strlen(name))
    {
        self.objectName = [NSString stringWithFormat:@"%s",name];
    }
}

- (void)purchaseById:(char*)productId
{
    if(productId && strlen(productId))
    {
        [[IAPurchase sharedPurchase] startRequestWithProductIdentifier:[NSString stringWithFormat:@"%s",productId]];
    }
}

- (void)restorePurchaseById:(char*)productId
{
    if(productId && strlen(productId))
    {
        self.restoreProductId = [NSString stringWithFormat:@"%s",productId];
        [[IAPurchase sharedPurchase] restorePurchase];
    }
}

- (void)restoreAllPurchases
{
    self.restoreProductId = nil;
    [[IAPurchase sharedPurchase] restorePurchase];
}

- (const char*)getJsonString:(NSDictionary*)dictonary
{
    NSString *jsonString = nil;
    if(dictonary)
    {
        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictonary
                                                           options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                             error:&error];
        
        if (! jsonData) {
            NSLog(@"Got an error: %@", error);
        } else {
            jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        }
    }
    
    if([jsonString length])
    {
        return [jsonString UTF8String];
    }
    
    return "";
}

#pragma mark - IAPurchaseDelegate

- (void)purchaseSuccess:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnPurchaseSuccess";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

- (void)purchaseFailed:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnPurchaseFailed";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

- (void)restoreFailed:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnRestoreFailed";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

// 所有购买过的产品全部restore成功的回调
// productIdentifiers数组里面存放的是每个产品的标识字符串。
// 如果没有购买过产品，那么productIdentifiers数组的长度为0，可以提示用户还未购买过产品；
// 否则处理restore逻辑
- (void)restoreCompletedWithProductIdentifiers:(NSArray *)productIdentifiers
{
    if(productIdentifiers && productIdentifiers.count)
    {
        if(0 == [_restoreProductId length])
        {
            //return all ids of products
            static NSString *methodName = @"OnRestoreQuerySuccess";
            if([self.objectName length])
            {
                NSDictionary* dict = @{@"product_ids":productIdentifiers};
                UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
            }
            
            return;
        }
        
        //return only one product id;
        for(NSString* iapId in productIdentifiers)
        {
            if([iapId isEqualToString:_restoreProductId])
            {
                static NSString *methodName = @"OnRestoreSuccess";
                if([self.objectName length])
                {
                    NSDictionary* dict = @{@"product_id":iapId};
                    UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
                }
                
                return;
            }
        }
    }
    
    //No purchase can restore.
    static NSString *methodName = @"OnNoRestore";
    if([self.objectName length])
    {
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],"");
    }
}

- (void)purchaseCanceled:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnPurchaseCancelled";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

- (void)restoreCanceled:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnRestoreCancelled";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

- (void)productRequestBegin:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnProductRequestBegin";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

- (void)productRequestEnd:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnProductRequestEnd";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

- (void)productsNotReady:(IAPurchase *)purchase
{
    static NSString *methodName = @"OnProductsNotReady";
    if([self.objectName length])
    {
        NSString* productId = nil;
        if(purchase)
            productId = purchase.curProductID;
        if(0 == productId.length)
            productId = @"";
        
        NSDictionary* dict = @{@"product_id":productId};
        UnitySendMessage([self.objectName UTF8String],[methodName UTF8String],[self getJsonString:dict]);
    }
}

@end

// When native code plugin is implemented in .mm / .cpp file, then functions
// should be surrounded with extern "C" block to conform C function naming rules
extern "C" {
    
    //To set the name of game object for UnitySendMessage method
    void _SetGameObjectNameForIAP(char* gameObjectName)
    {
        [[SSCIAPUnityAdapter getInstance] setGameObjectName:gameObjectName];
    }
    
    //To purchase
    void _PurchaseById(char* productId)
    {
        [[SSCIAPUnityAdapter getInstance] purchaseById:productId];
    }
    
    //To restore purchase by id
    void _RestorePurchaseById(char* productId)
    {
        [[SSCIAPUnityAdapter getInstance] restorePurchaseById:productId];
    }
    
    //To restore all purchases
    void _RestoreAllPurchases()
    {
        [[SSCIAPUnityAdapter getInstance] restoreAllPurchases];
    }
}
